using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;

namespace ACM.cmsarea08.Controls
{
    public enum FileModes
    {
        Stream,
        File
    }

    [DefaultProperty("FileStreamData")]
    [ToolboxData("<{0}:FileUpload runat=server></{0}:FileUpload>")]
    public class FileUpload : WebControl
    {




        private int maxsize = 4096;
        private string noext = ".exe,.bat,.com,.cgi,.dll";
        private string _uperror = "";
        private FileModes _tipoFile = FileModes.Stream;
        private string _filePath = "";

        protected System.Web.UI.WebControls.FileUpload fo_up;
        protected System.Web.UI.WebControls.LinkButton fo_delete;

        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        public string FileStreamData
        {
            get
            {
                String s = (String)ViewState[this.ID +"FileStreamData"];
                return ((s == null) ? String.Empty : s);
            }

            set
            {
                ViewState[this.ID+"FileStreamData"] = value;
            }
        }

        public FileModes FileMode
        {
            get { return _tipoFile; }
            set { _tipoFile = value; }
        }
        public string WriteablePath
        {
            get { return _filePath; }
            set { _filePath = value; }
        }

        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        public string JavascriptID
        {
            get
            {
                String s = (String)ViewState[this.ID + "JavascriptID"];
                return ((s == null) ? String.Empty : s);
            }

            set
            {
                ViewState[this.ID + "JavascriptID"] = value;
            }
        }
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        public bool EnableJavascriptAccess
        {
            get
            {
                if (ViewState[this.ID + "EnableJavascriptAccess"] != null)
                    return (bool)ViewState[this.ID + "EnableJavascriptAccess"];
                else
                    return false;
            }

            set
            {
                ViewState[this.ID + "EnableJavascriptAccess"] = value;
            }
        }

        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("200")]
        [Localizable(true)]
        [Description("Permette di definire la dimensione massima per singolo file caricato.")]
        public int MaxUploadSize
        {
            get
            {
                return maxsize;
            }

            set
            {
                maxsize = value;
            }
        }

        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue(".exe,.bat,.com,.cgi,.dll")]
        [Localizable(true)]
        [Description("Le estensioni in elenco separate da virgola definiscono la lista dei file NON accettati.")]
        public string NotAllowedFiles
        {
            get
            {
                return noext;
            }

            set
            {
                noext = value;
            }
        }

        private string CurrentKey
        {
            get
            {
                String s = (String)ViewState[this.ID + "FileKey"];
                return ((s == null) ? String.Empty : s);
            }

            set
            {
                ViewState[this.ID + "FileKey"] = value;
            }
        }

        public FileUpload(): base("div")
        {}

        protected override void OnInit(EventArgs e)
        {
			//System.Threading.Thread.CurrentThread.CurrentCulture.Name
			 string clang = ACM.cmsarea08.mainconfiguration.MainConf.LinguaPredefinita;
			 bool privateArea = true;
			 
			 if(this.Page is ACM.cmsarea08.Core.MainPage) {
			 	 privateArea=false;
				 if(ACM.cmsarea08.mainconfiguration.MainConf.ModelloLingua!=ACM.cmsarea08.LanguageModel.Single ) {
				 	if( ((ACM.cmsarea08.Core.MainPage)this.Page).Page_Lang != clang ) 
				 		clang = ((ACM.cmsarea08.Core.MainPage)this.Page).Page_Lang;
				 }
			 }
			 
			 if(ACM.cmsarea08.Users.CurrentUser.Autorizzato && privateArea)
				clang = ACM.cmsarea08.Users.CurrentUser.PrefLanguage;
			 
			
			if(System.Threading.Thread.CurrentThread.CurrentCulture.Name!= clang) {
  	  		    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(clang);
 			    System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(clang);
 		 	}				
			
            base.OnInit(e);
            fo_up = new System.Web.UI.WebControls.FileUpload();
            fo_delete = new System.Web.UI.WebControls.LinkButton();
            fo_delete.Text = "clear";
            fo_delete.Click += new EventHandler(EliminaStream);
            this.Controls.Add(fo_up);
            this.Controls.Add(fo_delete);
        }

        private void ClearCache()
        {
            if (CurrentKey == "") { CurrentKey = System.Guid.NewGuid().ToString(); return; }
            /*
            if (HttpContext.Current.Cache.Get("DATIIMG" + CurrentKey) != null)
                HttpContext.Current.Cache.Remove("DATIIMG" + CurrentKey);
            if (HttpContext.Current.Cache.Get("NAMEIMG" + CurrentKey) != null)
                HttpContext.Current.Cache.Remove("NAMEIMG" + CurrentKey);
            */
           ACM.cmsarea08.Function.CacheManager.cachemanager.RemoveCacheFileObject(CurrentKey);
            CurrentKey = System.Guid.NewGuid().ToString();
            return;
        }
        private string ClearFileName(string filaName)
        {
            //caratteri non ammessi: /\:*?"<>|
            string caratteriNO = "/\\:*?\"<>|'";
            foreach (char c in caratteriNO.ToCharArray())
                filaName = filaName.Replace(c, '_');
            return filaName;
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            //HttpContext.Current.Response.Write("MIE IMPOST : " + this.FileMode + ", WP: " + this.WriteablePath + "<hr/>");
            if (this.Page.IsPostBack)
            {
                if (fo_up.HasFile)
                {
                    
                    //Controllo size:
                    string filename = ClearFileName(fo_up.FileName);
                    string ext = "";
                    if (filename.IndexOf('.') == -1) { _uperror = Risorse.ControlsResource.FileUpload_extError; return; }
                    ext = filename.Substring(filename.LastIndexOf('.'));



                    if (noext.IndexOf(ext.ToLower()) != -1) { _uperror = Risorse.ControlsResource.FileUpload_extError; return; }
                    byte[] lettore = fo_up.FileBytes;

                    //HttpContext.Current.Response.Write("LUNG BYTE: " + lettore.Length + ", fileSTREAM LENG: " +
                    //    Convert.ToBase64String(lettore).Length + "<hr/>");
                    //HttpContext.Current.Response.Write("COMPRESSO: LUNG BYTE: " + lettoreCOMP.Length + ", fileSTREAM LENG: " +
                    //    Convert.ToBase64String(lettoreCOMP).Length + "<hr/>");
                    
                    if (lettore.Length > (maxsize * 1024)) { _uperror = Risorse.ControlsResource.FileUpload_sizeError; return; }
                    //byte[] lettoreCOMP = ACM.cmsarea08.formdataadapter.Adapter.Compress(lettore);
                    if (_tipoFile == FileModes.Stream)
                    {
                        ClearCache();
                        //HttpContext.Current.Cache.Add("DATIIMG" + CurrentKey, lettore, null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.NotRemovable, null);
                        //HttpContext.Current.Cache.Add("NAMEIMG" + CurrentKey, filename, null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.NotRemovable, null);
						ACM.cmsarea08.Function.CacheManager.cachemanager.setCacheFileObject(
                        	HttpContext.Current,
                        	CurrentKey,
                        	filename.Replace("#", "") + "#" + Convert.ToBase64String(lettore),
                        	180,false);
                        this.FileStreamData = filename.Replace("#", "") + "#" + Convert.ToBase64String(lettore);
                    }
                    else
                    {
                        //no path
                        if (_filePath.Trim().Length == 0) { this.FileStreamData = ""; throw new Exception("No WriteablePath for FileModes.File");   }
                        //no percorso
                        if (!System.IO.Directory.Exists(HttpContext.Current.Server.MapPath(_filePath.Trim()))) { this.FileStreamData = "";
                        throw new Exception("WriteablePath does not exists.");   }
                        try {
                            string path = _filePath.Trim();
                            if(path.EndsWith("/")) path=path.Substring(0,path.Length-1);
                            path += "/" + filename; 
                            //int counter = 1;
                            //(System.IO.File.Exists(HttpContext.Current.Server.MapPath(this.FileStreamData)))
                            //if (System.IO.File.Exists(HttpContext.Current.Server.MapPath(HttpContext.Current.Server.MapPath(path))))
                            //{
                            //    string path_1 = path.Substring(0, path.LastIndexOf('.'));
                            //    string path_e = path.Substring(path.LastIndexOf('.'));
                            //    path = path_1 + "(" + counter + ")" + path_e;
                            //    while (System.IO.File.Exists(HttpContext.Current.Server.MapPath(HttpContext.Current.Server.MapPath(path))))
                            //    {
                            //        counter++;
                            //        path = path_1 + "(" + counter + ")" + path_e;
                            //    }
                            //}

                            fo_up.SaveAs( HttpContext.Current.Server.MapPath( path) );
                            this.FileStreamData = path;
                        } catch (Exception ex) {
                            this.FileStreamData = "";
                            throw ex;
                            
                        }

                    }


                    }
            }
            if ( this.FileStreamData.Trim().Length>0)
            {
                if (this.FileMode == FileModes.Stream)
                {
                    if (this.FileStreamData.Length == 0) return;
                    if (this.FileStreamData.IndexOf('#') == -1) return;
                    //se ci sono dati:
                    try
                    {
                        string filename = ""; byte[] dati = new byte[0];
                        //filename = FileStreamData.Substring(0, FileStreamData.IndexOf('#'));
                       // dati = Convert.FromBase64String(FileStreamData.Substring(FileStreamData.IndexOf('#') + 1));
                        //if (filename.Length == 0) return;
                        //if (dati.Length == 0) return;
                        ClearCache();
//                        HttpContext.Current.Cache.Add("DATIIMG" + CurrentKey, dati, null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.NotRemovable, null);
//                        HttpContext.Current.Cache.Add("NAMEIMG" + CurrentKey, filename, null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.NotRemovable, null);
						  ACM.cmsarea08.Function.CacheManager.cachemanager.setCacheFileObject(
                        	HttpContext.Current,
                        	CurrentKey,
                        	FileStreamData,
                        	180,false);
                    }
                    catch
                    {
                        ClearCache();
                    }
                }
                else
                {
                    byte[] dati = new byte[0];
                    string filename = "";
                    if (this.FileStreamData.Length == 0) return;
                    if (!System.IO.File.Exists(HttpContext.Current.Server.MapPath(this.FileStreamData))) {
                        //throw new Exception("NON ESISTE: " + HttpContext.Current.Server.MapPath(this.FileStreamData));
                        return; }
                    try
                    {
                        System.IO.FileStream frf = new FileStream(HttpContext.Current.Server.MapPath(this.FileStreamData.Trim()), System.IO.FileMode.Open);
                        filename = this.FileStreamData.Substring(this.FileStreamData.LastIndexOf('/') + 1);
                        long lungo = frf.Length;
                        long pos = 0;
                        dati = new byte[lungo];
                        int reader = frf.ReadByte();
                        while (reader != -1)
                        {
                            dati[pos] = (byte)reader;
                            reader = frf.ReadByte();
                            pos++;
                        }
                        frf.Close();
                        if (filename.Length == 0) return;
                        if (dati.Length == 0) return;
                        //HttpContext.Current.Response.Write("FILE : " + filename + ", BYTE: " + dati.Length + "<hr/>");
                        ClearCache();
                        //HttpContext.Current.Cache.Add("DATIIMG" + CurrentKey, dati, null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.NotRemovable, null);
                        //HttpContext.Current.Cache.Add("NAMEIMG" + CurrentKey, filename, null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.NotRemovable, null);
						  ACM.cmsarea08.Function.CacheManager.cachemanager.setCacheFileObject(
                        	HttpContext.Current,
                        	CurrentKey,
                        	filename.Replace("#", "") + "#" + Convert.ToBase64String(dati),
                        	180,false);						                        

                    }
                    catch //(Exception ex)
                    {
                        //HttpContext.Current.Response.Write("NON RIESCO A LEGGERE : " + ex.ToString());
                    }

                }
            }

        }
        protected override void OnPreRender(EventArgs e)
        {
            if (this.Visible)
            {
                //if CurrentKEY
                /*
                if (CurrentKey.Length == 0) CurrentKey = System.Guid.NewGuid().ToString();
                HttpContext.Current.Session.Add("FileUpload" + CurrentKey, "");
                HttpContext.Current.Session.Add("FileUpload_Name" + CurrentKey, ""); 
                 */
            }
            base.OnPreRender(e);
        }

        protected override void RenderContents(HtmlTextWriter output)
        {
            bool hasFile = false;
            if (FileStreamData.Length > 0)
                hasFile = true;
            string[] fileInput = new string[2];
            if (FileMode == FileModes.Stream)
            {
                if (FileStreamData.IndexOf('#') == -1) { hasFile = false; FileStreamData = ""; }
                if (hasFile)
                {

                    fileInput[0] = FileStreamData.Substring(0, FileStreamData.IndexOf('#'));
                }
            }
            else
            {
                fileInput[0] = this.FileStreamData.Substring(this.FileStreamData.LastIndexOf('/') + 1);
                if (!System.IO.File.Exists(HttpContext.Current.Server.MapPath(this.FileStreamData))) { hasFile = false; FileStreamData = ""; }
            }

            this.RenderBeginTag(output); 
            StringWriter buffer_s = new StringWriter();
            HtmlTextWriter buffer = new HtmlTextWriter(buffer_s);
            base.RenderContents(buffer);
            string basecode = buffer_s.ToString();
            string linkbutton = "";
            int insLine = -1;
            insLine = basecode.IndexOf("<input");
            if (basecode.IndexOf("<a ") != -1)
            {
                linkbutton = basecode.Substring(basecode.IndexOf("<a "));
                basecode = basecode.Substring(0, basecode.IndexOf("<a "));
            }
            
            if (hasFile)
            {
                basecode = basecode.Insert(insLine, "<img align=\"top\" src=\"" +
                "FileUploadHandler.ashx?k="+this.CurrentKey+"&ope=p" + //&dt=" + HttpUtility.UrlEncode(FileStreamData) + "" + 
                "\" width=\"35\" alt=\"file\" />");
            	basecode += "<div>"+HttpContext.GetGlobalResourceObject("AcmGlobals","current_file").ToString() + " ";
                basecode += "<b>" + fileInput[0] + "</b> - <a target=\"_blank\" href=\"FileUploadHandler.ashx?k=" + this.CurrentKey +
                	"&ope=d\">download</a>" +
                    (linkbutton != "" ?(" - "+ linkbutton ): "") +
                    "</div><br/>";
                basecode += "<div style=\"font-style:italic\">"+Risorse.ControlsResource.FileUpload_overwrite+"</div>";
                if (EnableJavascriptAccess && this.JavascriptID.Trim().Length>0)
                {
                    basecode += "<input type=\"hidden\" id=\"" + this.JavascriptID.Trim() + "\" value=\"" + this.FileStreamData + "\"/>";
                }
            }
            if (_uperror.Length > 0)
            {
                basecode += "<div style=\"color:red;\">"+_uperror+"</div>";
            }
//            	"lingua corrente: " +System.Threading.Thread.CurrentThread.CurrentCulture.Name+"<hr/>" +
            
            output.Write(
            	basecode);
            this.RenderEndTag(output);



        }

        private void EliminaStream(object o, EventArgs e)
        {
            if (this.FileMode == FileModes.Stream)
            {
                this.ClearCache();
            }
            else
            {
                if (System.IO.File.Exists(HttpContext.Current.Server.MapPath(this.FileStreamData)))
                {
                    System.IO.File.Delete(HttpContext.Current.Server.MapPath(this.FileStreamData));
                    this.ClearCache();
                }
            }
            this.FileStreamData = string.Empty;
        }
    }
}
